package au.edu.swin.videoshop.bean;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Comparator;
import java.util.Date;

import au.edu.swin.videoshop.service.MiscUtil;

public class Rental implements Serializable{
	private Long mRentalId;
	private TitleCopy mTitleCopy;
	private Staff mStaff;
	private Customer mCustomer;
	private BigDecimal mFirstCharge;
	private BigDecimal mFinalCharge;
	private Date mRentalDate;
	private Date mDueDate;
	private Date mReturnDate;
	private RentalStatus mStatus;
	
	public Rental() {
	}
	
	/**
	 * @return the titleCopy
	 */
	public TitleCopy getTitleCopy() {
		return mTitleCopy;
	}
	/**
	 * @param titleCopy the titleCopy to set
	 */
	public void setTitleCopy(TitleCopy titleCopy) {
		mTitleCopy = titleCopy;
	}
	/**
	 * @return the staff
	 */
	public Staff getStaff() {
		return mStaff;
	}
	/**
	 * @param staff the staff to set
	 */
	public void setStaff(Staff staff) {
		mStaff = staff;
	}
	/**
	 * @return the customer
	 */
	public Customer getCustomer() {
		return mCustomer;
	}
	/**
	 * @param customer the customer to set
	 */
	public void setCustomer(Customer customer) {
		mCustomer = customer;
	}

	/**
	 * @return the rentalId
	 */
	public Long getRentalId() {
		return mRentalId;
	}

	/**
	 * @param rentalId the rentalId to set
	 */
	public void setRentalId(Long rentalId) {
		mRentalId = rentalId;
	}

	/**
	 * @return the firstCharge
	 */
	public BigDecimal getFirstCharge() {
		return mFirstCharge;
	}

	/**
	 * @param firstCharge the firstCharge to set
	 */
	public void setFirstCharge(BigDecimal firstCharge) {
		mFirstCharge = MiscUtil.round(firstCharge);
	}

	/**
	 * @return the finalCharge
	 */
	public BigDecimal getFinalCharge() {
		return mFinalCharge;
	}

	/**
	 * @param finalCharge the finalCharge to set
	 */
	public void setFinalCharge(BigDecimal finalCharge) {
		mFinalCharge = MiscUtil.round(finalCharge);
	}

	/**
	 * @return the rentalDate
	 */
	public Date getRentalDate() {
		return mRentalDate;
	}

	/**
	 * @param rentalDate the rentalDate to set
	 */
	public void setRentalDate(Date rentalDate) {
		mRentalDate = MiscUtil.normaliseDate(rentalDate);
	}

	/**
	 * @return the dueDate
	 */
	public Date getDueDate() {
		return mDueDate;
	}

	/**
	 * @param dueDate the dueDate to set
	 */
	public void setDueDate(Date dueDate) {
		mDueDate = MiscUtil.normaliseDate(dueDate);
	}

	/**
	 * @return the returnDate
	 */
	public Date getReturnDate() {
		return mReturnDate;
	}

	/**
	 * @param returnDate the returnDate to set
	 */
	public void setReturnDate(Date returnDate) {
		mReturnDate = MiscUtil.normaliseDate(returnDate);
	}

	/**
	 * @return the status
	 */
	public RentalStatus getStatus() {
		return mStatus;
	}

	/**
	 * @param status the status to set
	 */
	public void setStatus(RentalStatus status) {
		mStatus = status;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj instanceof Rental) {
			if (this.mRentalId != null) {
				return this.mRentalId.equals(((Rental)obj).mRentalId);
			}
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		return mRentalId.hashCode();
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return mRentalId.toString();
	}
	
	public static class TitleNameComparator implements Comparator{

		/* (non-Javadoc)
		 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
		 */
		public int compare(Object o1, Object o2) {
			return ((Rental)o1).getTitleCopy().getMedium().getTitle().getTitleName().compareTo(((Rental)o2).getTitleCopy().getMedium().getTitle().getTitleName());
		}
	}
	
	public static class MediumTypeComparator implements Comparator{

		/* (non-Javadoc)
		 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
		 */
		public int compare(Object o1, Object o2) {
			return ((Rental)o1).getTitleCopy().getMedium().getMediumType().getName().compareTo(((Rental)o2).getTitleCopy().getMedium().getMediumType().getName());
		}
	}
	
	public static class StoreNameComparator implements Comparator{

		/* (non-Javadoc)
		 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
		 */
		public int compare(Object o1, Object o2) {
			return ((Rental)o1).getTitleCopy().getStore().getStoreName().compareTo(((Rental)o2).getTitleCopy().getStore().getStoreName());
		}
	}
	
	public static class DueDateComparator implements Comparator{

		/* (non-Javadoc)
		 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
		 */
		public int compare(Object o1, Object o2) {
			return ((Rental)o1).getDueDate().compareTo(((Rental)o2).getDueDate());
		}
	}
	
	public static class ReturnDateComparator implements Comparator{

		/* (non-Javadoc)
		 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
		 */
		public int compare(Object o1, Object o2) {
			Rental r1 = (Rental)o1;
			Rental r2 = (Rental)o2;
			
			if (r1.getReturnDate() == null && r2.getReturnDate() != null) {
				return -1;
			}
			else if (r1.getReturnDate() != null && r2.getReturnDate() == null) {
				return 1;
			}
			else if (r1.getReturnDate() == null && r2.getReturnDate() == null) {
				return 0;
			}
			else {
				return r1.getReturnDate().compareTo(r2.getReturnDate());
			}
		}
	}
	
	public static class StatusComparator implements Comparator{

		/* (non-Javadoc)
		 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
		 */
		public int compare(Object o1, Object o2) {
			return ((Rental)o1).getStatus().compareTo(((Rental)o2).getStatus());
		}
	}
	
}
